/*
 * @Author: xiaosihan
 * @Date: 2022-05-15 14:17:57
 * @Last Modified by: xiehangyun
 * @Last Modified time: 2025-02-20 14:33:27
 */

import { fabric } from "fabric";
import { ICanvasOptions } from "fabric/fabric-impl";
import { get, set } from "lodash";
import FabricBarCode from "./FabricBarCode";
import FabricImage from "./FabricImage";
import FabricMark from "./FabricMark";
import FabricText from "./FabricText";
import fontManage from "./fontManage";
import mtrPNG from "./icon/mtr.png";

fabric.Object.prototype.transparentCorners = false;
fabric.Object.prototype.cornerStrokeColor = '#cccccc';
fabric.Object.prototype.cornerColor = '#ffffff';
fabric.Object.prototype.cornerStyle = 'circle';
fabric.Object.prototype.cornerSize = 14;
fabric.Object.prototype.borderScaleFactor = 2;

//@ts-ignore  默认的最大缓存画布4096导出时不够用,  换成 8192
fabric.maxCacheSideLimit = 8192;

// 旋转控制器
const mtrContorls = new class MtrContorls extends fabric.Control {

  icon = (() => {
    const icon = new fabric.Image("");
    icon.setSrc(mtrPNG, () => {
      icon.set({
        scaleX: 0.1,
        scaleY: 0.1,
      });
    }, { crossOrigin: 'anonymous' });
    return icon;
  })();

  x = 0;
  y = -0.5;

  offsetY = -40;

  //@ts-ignore
  actionHandler = fabric.controlsUtils.rotationWithSnapping;
  //@ts-ignore
  cursorStyleHandler = fabric.controlsUtils.rotationStyleHandler;
  withConnection = true;
  actionName = "rotate";

  render(ctx: CanvasRenderingContext2D, left: number, top: number, styleOverride: any, fabricObject: fabric.Object) {
    this.icon.set({
      originX: "center",
      originY: "center",
      left,
      top,
      angle: fabricObject.angle
    });
    this.icon.render(ctx);
  }
};

set(fabric.Object.prototype.controls, ['mtr'], mtrContorls);

//数值保留的小数位数
fabric.Object.NUM_FRACTION_DIGITS = 6;
//@ts-ignore 不限制cacheCanvas 的尺寸大小
fabric.perfLimitSizeTotal = Infinity;


// fabric拓展基类
export default class FabricCanvas extends fabric.Canvas {

  constructor(element: HTMLCanvasElement | string | null, options?: ICanvasOptions) {

    super(element, options);

    const upperCanvasEl = this.getSelectionElement();
    upperCanvasEl.style.zIndex = "10";

  }

  // 把 控制器绘制到 upererElement 上
  //@ts-ignore
  drawControls(ctx: CanvasRenderingContext2D) {
    var activeObject = this._activeObject;

    //@ts-ignore
    const topCxt = this.getTopContext();

    topCxt.clearRect(0, 0, this.getWidth(), this.getHeight());

    if (activeObject) {
      //@ts-ignore
      activeObject._renderControls(topCxt);
    }
  }

  // 离屏渲染用的
  declare contextTop: CanvasRenderingContext2D;
  // 主要的画布对象
  declare lowerCanvasEl: CanvasRenderingContext2D;

  // 保留对象的渲染顺序,  选中的对象,不需要绘制在最前面
  preserveObjectStacking = true;

  //  加载画布数据
  loadFromJSON(json: any, callback: Function, reviver?: Function | undefined): fabric.Canvas {
    // 设置画布的背景
    // set(json, ['background'], '');
    // delete json['background'];
    return super.loadFromJSON(json, async () => {
      const objects: Array<any> = get(json, ['objects']) || [];
      // 加载用到的字体
      await fontManage.loadFont(objects.map(o => o.fontFamily));
      callback();
    }, reviver);
  }

  //是否锁住了
  isLock(object: fabric.Object) {
    return object.lockMovementX &&
      object.lockMovementY &&
      object.lockRotation &&
      object.lockScalingX &&
      object.lockScalingY &&
      object.lockSkewingX &&
      object.lockSkewingY
  }

  //锁住的对象拾取时,最后拾取
  _searchPossibleTargets(objects: Array<FabricImage | FabricText | FabricBarCode>, pointer: any) {

    let newObjects: Array<FabricImage | FabricText | FabricBarCode> = [];

    // 未锁定的排在前面
    objects.map(o => {
      if (o.type !== "barCode" && this.isLock(o)) {
        newObjects.push(o);
      }
    });
    // 锁定的排在后面
    objects.map(o => {
      if (o.type !== "barCode" && !this.isLock(o)) {
        newObjects.push(o);
      }
    });
    // 条码对象放最前面
    objects.map(o => {
      if (o.type === "barCode") {
        newObjects.push(o);
      }
    });

    //@ts-ignore
    const target = super._searchPossibleTargets(newObjects, pointer);

    return target;
  }

  // 画布轮廓裁剪对象
  fabricMark?: FabricMark;

  //不绘制绘制背景的方法
  _renderBackground(ctx: CanvasRenderingContext2D) {
    // if (!this.backgroundColor) {
    //     return;
    // }
  }

}



